#ifndef SIMPLE_IO_READER_BUFF_H
#define SIMPLE_IO_READER_BUFF_H

#include <vector>
#include <string>

// TODO 优化缓冲区, 使用环形数组模式
namespace simple {
    /**
     * 代缓冲区功能的IO读取器, 不是线程安全
     */
    class ReaderBuff {
    private:
        // io句柄
        int read_fd_;
        // 缓冲区大小
        int buff_size_ = 2048;
        // 缓冲区指针
        char *buff_data_ = nullptr;
        // 读取指针
        int volatile read_index = 0;
        // 写入指针
        int volatile write_index = 0;

        /**
         * 从io句柄读取数据, 写入缓冲区
         *
         * @return 写入的字节数, 0表示没有写入数据, -1写入错误
         */
        int readFD();

        /**
         * 从io句柄读取数据, 写入缓冲区, 强制刷新缓冲区
         */
        int readFDForce();

        /**
         * 从缓冲区读取数据, 写入到指定位置
         *
         * @return 读取的字节数, 0表示没有读取数据, -1读取错误
         */
        int readBuff(void *dest, int size);

    public:
        /**
         * 构造函数, 默认缓冲区大小为2048
         *
         * @param read_fd io句柄
         */
        explicit ReaderBuff(int read_fd);

        /**
         * 构造函数
         *
         * @param read_fd io句柄
         * @param buff_size 缓冲区大小
         */
        ReaderBuff(int read_fd, int buff_size);

        /**
         * 读取一个字节
         */
        int readByte(void *);

        /**
         * 读取指定字节数
         *
         * @param ptr 读取数据写入的地址
         * @param size 读取的字节数
         */
        int readBytes(void *ptr, int);

        /**
         * 读取一行数据, 直到遇到换行符, 返回读取的字符串
         */
        std::string readLine();

        /**
         * 读取一行数据, 直到遇到换行符, 返回读取的字符数
         */
        int readLine(std::vector<char> &buf);

        /**
         * 读取一行数据, 直到遇到换行符, 返回读取的字符数
         *
         * @param buf 读取到的数据
         * @param maxLength 最大读取长度, 不能超过缓冲区大小
         * @return 读取的字符数, -1表示读取错误, 0没有读到换行符
         */
        int readLine(std::vector<char> &buf, int maxLength);

        /**
         * 探测指定长度字节, 不改变读取指针位置, 使用数组接收
         *
         * @param dest 探测到的数据写到这个地址
         * @param size 探测的长度
         * @return 探测到的字节数, -1表示读取错误
         */
        int peek(void *dest, int size);

        /**
         * 探测指定长度字节, 不改变读取指针位置, 使用向量接收
         *
         * @param buf 探测到的数据
         * @param size 指定探测长度
         * @return 探测到的字节数, -1表示读取错误
         */
        int peek(std::vector<char> &buf, int size);

        /**
         * 缓存中可被读取的字节数
         */
        [[nodiscard]] int buffered() const;

        /**
         * 缓冲区的大小
         */
        [[nodiscard]] int size() const;

        /**
         * 重置缓冲区
         */
        void reset();
    };
}
#endif //SIMPLE_IO_READER_BUFF_H
